gusucode.com > VC++ EMF图片浏览器(可读emf、wmf、emz、wmz、png……等)-源码程序 > VC++ EMF图片浏览器(可读emf、wmf、emz、wmz、png……等)-源码程序/code/Src/Client/scemflib/SCDCRendPaths_i.cpp

    //Download by http://www.NewXing.com
/*
*	This file is part of the EMFexplorer projet.
*	Copyright (C) 2004 Smith Charles.
*
*	This library is free software; you can redistribute it and/or
*	modify it under the terms of the GNU Lesser General Public
*	License as published by the Free Software Foundation; either
*	version 2.1 of the License, or (at your option) any later version.
*
*   This library is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*   Lesser General Public License for more details.
*
*   You should have received a copy of the GNU Lesser General Public
*   License along with this library; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
*
*	Extension: for commercial use, apply the Equity Public License, which
*	adds to the normal terms of the GLPL a condition of donation to the author.
*   If you are interested in support for this source code,
*   contact Smith Charles <smith.charles@free.fr> for more information.
*/

#include "stdafx.h"
#include "SCEMFdcRenderer.h"

using namespace Gdiplus;

///////////////////////////////////////////////////////////////////////////////////////
// Paths management
//
// Windows NT: The following drawing functions define points in a path: 
//	
//	AngleArc	CloseFigure	MoveToEx		PolyDraw	PolyPolygon		TextOut	
//	Arc			Ellipse		Pie				Polygon		PolyPolyline		
//	ArcTo		ExtTextOut	PolyBezier		Polyline	Rectangle    	
//	Chord		LineTo		PolyBezierTo	PolylineTo	RoundRect  	
//	
//	
// Windows 95 and Windows 98: When constructing a path, only the
//
// CloseFigure, ExtTextOut, LineTo, MoveToEx, PolyBezier, PolyBezierTo,
// Polygon, Polyline, PolylineTo, PolyPolygon, PolyPolyline, and TextOut
//
// functions are recorded.
///////////////////////////////////////////////////////////////////////////////////////

///
/// Open a path bracket. Note that:
///	- SaveDC/RestoreDC are not legal during path recording.
///	- BeginPath/EndPath are not legal during path recording.
/// So we don't really need a path holder for reference counting.
/// But what if a SaveDC/RestoreDC pair occurs just after EndPath, but
/// BEFORE stroking or filling the current path? We don't know. So just in case...
///
void CSCEMFdcRenderer::SCBeginPath()
{
	ASSERT(m_pGraphics);
	
	// Discard any existing path
	SC_OBJHOLDER_RELEASE_T(m_pPathHolder, m_pPath, SCPath);

	m_pPath = new SCPath((ALTERNATE==m_dwFillMode) ? FillModeAlternate : FillModeWinding);

	SC_OBJHOLDER_RENEW_T(m_pPathHolder, m_pPath, SCPath);
}

void CSCEMFdcRenderer::SCCloseFigure()
{
	ASSERT(m_pGraphics);
	ASSERT(m_pPath);
	m_pPath->CloseFigure();
}

///
/// Close a path bracket. 
///
void CSCEMFdcRenderer::SCEndPath()
{
	ASSERT(m_pGraphics);
	ASSERT(m_pPath);

	// No GDI+ equivalent action

	// But this object is now in a fragile state. If no fucntion is called that clears
	// the path (stroke, fill, etc.), no drawing will occur.
	m_pPath->SCSetEnd();
}

///
/// Discard a path bracket. 
///
void CSCEMFdcRenderer::SCAbortPath()
{
	ASSERT(m_pGraphics);
	ASSERT(m_pPath);
	SC_OBJHOLDER_RELEASE_T(m_pPathHolder, m_pPath, SCPath);
}

void CSCEMFdcRenderer::SCApplyPath(DWORD dwDrawType/*=SC_PATH_STROKEANDFILL*/, INT iClipMode/*=RGN_COPY*/)
{
	ASSERT(m_pGraphics);
	// ASSERT(m_pPath);
	if (!m_pPath)
		return;

	if (SC_PATH_CLIP==dwDrawType)
	{
		m_pGraphics->SetClip(m_pPath, SCClipModeFormRGNMode(iClipMode));
		if (RGN_COPY==iClipMode)
			SCCropToPlayBox(CombineModeIntersect);
	} else
	{
		if (dwDrawType & SC_PATH_FILL)
		{
			ASSERT(m_pBrush);
			m_pGraphics->FillPath(m_pBrush, m_pPath);
		}
		if (dwDrawType & SC_PATH_STROKE)
		{
			ASSERT(m_pPen);
			m_pGraphics->DrawPath(m_pPen, m_pPath);
		}
	}
	
	// Discard the path after using it
	// (We're trying to mimic GDI, not playing any bogus EMF.)
	SC_OBJHOLDER_RELEASE_T(m_pPathHolder, m_pPath, SCPath);
}

void CSCEMFdcRenderer::SCFlattenPath()
{
	ASSERT(m_pGraphics);
	ASSERT(m_pPath);
	m_pPath->Flatten();
}

void CSCEMFdcRenderer::SCWidenPath()
{
	ASSERT(m_pGraphics);
	ASSERT(m_pPath);
	ASSERT(m_pPen);

	m_pPath->Widen(m_pPen);
}

///
///	Use a computed path as clipping region.
///
void CSCEMFdcRenderer::SCSetClipPath(LPCPOINT pPoints, LPCBYTE pTypes, DWORD dwCount, INT iClipMode)
{
	ASSERT(m_pGraphics);

	FillMode fillMode = (ALTERNATE==m_dwFillMode) ? FillModeAlternate : FillModeWinding;
	GraphicsPath CurPath((Point*)pPoints, pTypes, dwCount, fillMode);

	m_pGraphics->SetClip(&CurPath, SCClipModeFormRGNMode(iClipMode));
	if (RGN_COPY==iClipMode)
		SCCropToPlayBox(CombineModeIntersect);
}

///
///	Fill/stroke a computed path.
///
void CSCEMFdcRenderer::SCDrawPath(LPCPOINT pPoints, LPCBYTE pTypes, DWORD dwCount, DWORD dwDrawType/*=SC_PATH_STROKEANDFILL*/)
{
	ASSERT(m_pGraphics);

	FillMode fillMode = (ALTERNATE==m_dwFillMode) ? FillModeAlternate : FillModeWinding;
	GraphicsPath CurPath((Point*)pPoints, pTypes, dwCount, fillMode);

	if (dwDrawType & SC_PATH_FILL)
	{
		ASSERT(m_pBrush);
		m_pGraphics->FillPath(m_pBrush, &CurPath);
	}

	if (dwDrawType & SC_PATH_STROKE)
	{
		ASSERT(m_pPen);
		m_pGraphics->DrawPath(m_pPen, &CurPath);
	}
}